//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.base;

import TUIO.TuioClient;
import TUIO.TuioCursor;
import TUIO.TuioListener;
import TUIO.TuioObject;
import TUIO.TuioTime;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import javafx.geometry.Point2D;
import org.tuiofx.Configuration;
import org.tuiofx.TangibleEvent;
import org.tuiofx.TangibleListener;
import org.tuiofx.internal.gesture.TuioTouchPoint;
import org.tuiofx.internal.gesture.TuioTouchPoint.State;
import org.tuiofx.internal.util.LogUtils;

public class TuioInputService implements TuioListener {
    private final Configuration config;
    private final CoordinatesMapping coordinatesMapping;
    private TouchHandler touchHandler;
    private TuioClient tuioclient;
    private HashMap<Long, Integer> aliveCursorList;
    private Vector<TangibleListener> tangibleListeners;

    public TuioInputService(CoordinatesMapping coordinatesMapping, TouchHandler touchHandler, Configuration config) {
        this.coordinatesMapping = coordinatesMapping;
        this.touchHandler = touchHandler;
        this.config = config;
        this.aliveCursorList = new HashMap<>();
        this.tuioclient = new TuioClient(config.getPort());
        this.tuioclient.addTuioListener(this);
        this.tuioclient.connect();
        if (!this.tuioclient.isConnected()) {
            System.out.println("Stopppping execution as selected TUIO port is currently occupied");
            System.exit(0);
        }

        if (this.config.isDebugModeEnabled()) {
            LogUtils.debug("Started TUIOClient and TouchHandler");
        }

    }

    public void addTuioCursor(TuioCursor tuioCursor) {
        if (!config.isHandlerCursorEvent()) {
            return;
        }
        Integer aliveCursorID = this.aliveCursorList.get(tuioCursor.getSessionID());
        if (aliveCursorID != null) {
            LogUtils.warn("CURSOR ID: " + tuioCursor.getCursorID() + " SESSION_ID: " + tuioCursor.getSessionID() + " is still alive");
        } else {
            this.aliveCursorList.put(tuioCursor.getSessionID(), tuioCursor.getCursorID());
            TuioTouchPoint touchPoint = this.createTouchPoint(tuioCursor, State.STARTED);
            this.touchHandler.touchesBegan(touchPoint);
        }
    }

    public void updateTuioCursor(TuioCursor tuioCursor) {
        if (!config.isHandlerCursorEvent()) {
            return;
        }
        Integer aliveCursorID = this.aliveCursorList.get(tuioCursor.getSessionID());
        if (aliveCursorID == null) {
            LogUtils.warn("UPDATE CURSOR FAILED - CURSOR IS NOT ALIVE  ID: " + tuioCursor.getCursorID() + " SESSION_ID: " + tuioCursor.getSessionID());
        } else {
            TuioTouchPoint touchPoint = this.createTouchPoint(tuioCursor, State.MOVED);
            this.touchHandler.touchesMove(touchPoint);
        }
    }

    public void removeTuioCursor(TuioCursor tuioCursor) {
        if (!config.isHandlerCursorEvent()) {
            return;
        }
        Integer aliveCursorID = this.aliveCursorList.get(tuioCursor.getSessionID());
        if (aliveCursorID == null) {
            LogUtils.warn("REMOVE CURSOR FAILED - CURSOR IS NOT ALIVE  ID: " + tuioCursor.getCursorID() + " SESSION_ID: " + tuioCursor.getSessionID());
        } else {
            boolean res = this.aliveCursorList.remove(tuioCursor.getSessionID(), tuioCursor.getCursorID());
            this.touchHandler.touchesEnd(this.createTouchPoint(tuioCursor, State.ENDED));
            if (!res) {
                LogUtils.error("+++++++++++++Failed to remove the cursor from the list");
            }

        }
    }

    private TuioTouchPoint createTouchPoint(TuioCursor tuioCursor, TuioTouchPoint.State state) {
        Point2D screenCords = this.coordinatesMapping.computeTuioTouchToScreenCoordinates(tuioCursor.getX(), tuioCursor.getY());
        Point2D sceneCords = this.coordinatesMapping.computeTuioTouchToSceneCoordinates(tuioCursor.getX(), tuioCursor.getY());
        return new TuioTouchPoint(tuioCursor, screenCords.getX(), screenCords.getY(), sceneCords.getX(), sceneCords.getY(), state);
    }

    public void refresh(TuioTime tuioTime) {
    }

    public void addTuioObject(TuioObject tuioObject) {
        Point2D screenCords = this.coordinatesMapping.computeTuioTouchToScreenCoordinates(tuioObject.getX(), tuioObject.getY());
        TangibleEvent tangible = new TangibleEvent(TangibleEvent.TANGIBLE_ADDED, tuioObject.getSymbolID(), screenCords.getX(), screenCords.getY(), tuioObject.getAngleDegrees(), tuioObject.getRotationSpeed(), tuioObject.getRotationAccel());
        this.informTuioTangibleListeners(tangible);
    }

    public void updateTuioObject(TuioObject tuioObject) {
        Point2D screenCords = this.coordinatesMapping.computeTuioTouchToScreenCoordinates(tuioObject.getX(), tuioObject.getY());
        TangibleEvent tangible = new TangibleEvent(TangibleEvent.TANGIBLE_UPDATED, tuioObject.getSymbolID(), screenCords.getX(), screenCords.getY(), tuioObject.getAngleDegrees(), tuioObject.getRotationSpeed(), tuioObject.getRotationAccel());
        this.informTuioTangibleListeners(tangible);
    }

    public void removeTuioObject(TuioObject tuioObject) {
        Point2D screenCords = this.coordinatesMapping.computeTuioTouchToScreenCoordinates(tuioObject.getX(), tuioObject.getY());
        TangibleEvent tangible = new TangibleEvent(TangibleEvent.TANGIBLE_REMOVED, tuioObject.getSymbolID(), screenCords.getX(), screenCords.getY(), tuioObject.getAngleDegrees(), tuioObject.getRotationSpeed(), tuioObject.getRotationAccel());
        this.informTuioTangibleListeners(tangible);
    }

    private void informTuioTangibleListeners(TangibleEvent tangible) {
        if (this.tangibleListeners != null) {
            Iterator<TangibleListener> var2 = this.tangibleListeners.iterator();

            while (var2.hasNext()) {
                TangibleListener tangibleListener = var2.next();
                if (tangible.getEventType() == TangibleEvent.TANGIBLE_ADDED) {
                    tangibleListener.tuioTangibleAdded(tangible);
                } else if (tangible.getEventType() == TangibleEvent.TANGIBLE_REMOVED) {
                    tangibleListener.tuioTangibleRemoved(tangible);
                } else if (tangible.getEventType() == TangibleEvent.TANGIBLE_UPDATED) {
                    tangibleListener.tuioTangibleUpdated(tangible);
                }
            }
        }

    }

    public void addTangibleListener(TangibleListener tangibleListener) {
        if (this.tangibleListeners == null) {
            this.tangibleListeners = new Vector<>();
        }

        this.tangibleListeners.add(tangibleListener);
    }

    public void removeTangibleListener(TangibleListener tangibleListener) {
        if (this.tangibleListeners != null) {
            this.tangibleListeners.remove(tangibleListener);
        }

    }

    public void removeAllTangibleListener() {
        if (this.tangibleListeners != null) {
            this.tangibleListeners.clear();
        }

    }

    public void disconnectTUIO() {
        this.tuioclient.disconnect();
        LogUtils.debug("disconnect TUIO");
    }
}
